package ru.spbau.database.group3.memoryManager;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author: stas
 * @date: 2/2/13
 * @time: 10:28 PM
 */
public class BufferManager {

    public ByteBuffer getPageData(int pid) throws IOException {
        if(bufferPool.containsKey(pid)) {
            return bufferPool.get(pid);
        }
        return fetchPageData(pid);
    }

    public static BufferManager getInstance() {
        return INSTANCE;
    }

    public static void flushPool() {
        for(MappedByteBuffer pageData : bufferPool.values()) {
            pageData.force();
        }
    }

    private ByteBuffer fetchPageData(Integer pid) throws IOException {
        if(POOL_SIZE < bufferPool.size()) {
            cleanPool();
        }
        MappedByteBuffer pageData = spaceManager.getPageData(pid);
        pageData.load();
        bufferPool.put(pid, pageData);
        return pageData;
    }

    private void cleanPool() throws IOException {
        Map.Entry<Integer, MappedByteBuffer> head = bufferPool.pollFirstEntry();
        spaceManager.flushPageData(head.getValue());
    }


    private BufferManager() {}

    private static final int POOL_SIZE = 100;
    private static final TreeMap<Integer, MappedByteBuffer> bufferPool = new TreeMap<Integer, MappedByteBuffer>();
    private static final SpaceManager spaceManager = SpaceManager.getInstance();
    private static final BufferManager INSTANCE = new BufferManager();

}
